﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xrm.Sdk.Workflow;
using System.Activities;
using Microsoft.Xrm.Sdk;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Crm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using System.Xml.Serialization;
using System.IO;
using System.Runtime.Serialization;
using System.Xml;
using System.Text.RegularExpressions;

/**
 * Copyright 2011 by Alberto Gemin
 * agemin@hotmail.com
 * Version 1.7.0.1
 * 13 Dec 2011
 **/
namespace Gemina.CRM2011.WF.LdgManager
{
/*    [AgCodeActivity(ActivityNameCompareUserViewSets, AgViewsUtils.GroupName)]
    public class AgCompareUserViewSets : AgCodeActivityBase
    {

        #region Constants

        private const string ActivityNameCompareUserViewSets = "Compare User View Sets";
        private const string Param1InputViewDefinitions1 = "View Definitions (Set 1)";
        private const string Param2InputViewDefinitions2 = "View Definitions (Set 2)";
        private const string Param1OutputIsDifferent = "Is Different";
        private const string Param2OutputDifferences = "Differences' Report";
        private const string MsgNull2 = "{0} and {1} cannot be null.";

        #endregion

        #region Properties

        public List<Entity> ValidatedDefinitions1 { get; set; }
        public List<Entity> ValidatedDefinitions2 { get; set; }

        #endregion

        #region Workflow Input Parameters

        /// <summary>
        /// Input parameter
        /// </summary>
        [Input(Param1InputViewDefinitions1)]
        [RequiredArgument]
        public InArgument<String> InputViewDefinitions1 { get; set; }

        /// <summary>
        /// Input parameter
        /// </summary>
        [Input(Param2InputViewDefinitions2)]
        [RequiredArgument]
        public InArgument<String> InputViewDefinitions2 { get; set; }

        #endregion

        #region Workflow Output Parameters

        /// <summary>
        /// Output parameter
        /// </summary>
        [Output(Param1OutputIsDifferent)]
        public OutArgument<bool> OutputIsDifferent { get; set; }

        /// <summary>
        /// Output parameter
        /// </summary>
        [Output(Param2OutputDifferences)]
        public OutArgument<string> OutputDifferences { get; set; }

        #endregion

        #region CodeActivity

        override protected bool ExecuteBody(CodeActivityContext executionContext)
        {
            this.CheckArguments(executionContext);
            StringBuilder diff = new StringBuilder();
            bool isDifferent = this.CompareSets(diff);

            this.OutputIsDifferent.Set(executionContext, isDifferent);
            this.OutputDifferences.Set(executionContext, diff.ToString());

            return true;
        }

        #endregion

        #region Local Methods

        private void CheckArguments(CodeActivityContext executionContext)
        {
            string strDefinitions1 = this.InputViewDefinitions1.Get(executionContext);
            string strDefinitions2 = this.InputViewDefinitions2.Get(executionContext);
            if (String.IsNullOrEmpty(strDefinitions1) || String.IsNullOrEmpty(strDefinitions2))
            {
                throw new AgErrorMessage(String.Format(MsgNull2, Param1InputViewDefinitions1, Param2InputViewDefinitions2));
            }
            this.ValidatedDefinitions1 = this.DeserializeEntities(strDefinitions1);
            this.ValidatedDefinitions2 = this.DeserializeEntities(strDefinitions2);
        }

        private bool CompareSets(StringBuilder diff)
        {
            string line = "* Comparing:" + Environment.NewLine;
            diff.Append(line);
            int origLen = diff.Length;

            Dictionary<string, Entity> set1 = new Dictionary<string, Entity>();
            foreach (Entity uq in this.ValidatedDefinitions1)
            {
                string name = uq.GetAttributeValue<string>(AgViewsUtils.FieldName);
                while (set1.ContainsKey(name))
                {
                    name = name + "*";
                }
                set1.Add(name, uq);
            }

            Dictionary<string, Entity> set2 = new Dictionary<string, Entity>();
            foreach (Entity uq in this.ValidatedDefinitions2)
            {
                string name = uq.GetAttributeValue<string>(AgViewsUtils.FieldName);
                while (set2.ContainsKey(name))
                {
                    name = name + "*";
                }
                set2.Add(name, uq);
            }

            foreach (string name in set1.Keys)
            {
                if (set2.ContainsKey(name))
                {
                    Entity toView = set2[name];
                    this.CompareViewPair(set1[name], toView, diff);
                    set2.Remove(name);
                }
                else
                {
                    this.CompareViewPair(set1[name], null, diff);
                }
            }

            foreach (Entity toView in set2.Values)
            {
                this.CompareViewPair(null, toView, diff);
            }

            if (diff.Length == origLen)
            {
                line = "   -- No differences." + Environment.NewLine;
                diff.Append(line);
                return false;
            }
            else
            {
                return true;
            }
        }

        private void CompareViewPair(Entity fromView, Entity toView, StringBuilder diff)
        {
            StringBuilder sb = new StringBuilder();
            if (fromView == null)
            {
                sb.Append("   -- View \"" + toView.GetAttributeValue<string>(AgViewsUtils.FieldName) + "\" exists only in set 2." + Environment.NewLine);
            }
            else if (toView == null)
            {
                sb.Append("   -- View \"" + fromView.GetAttributeValue<string>(AgViewsUtils.FieldName) + "\" exists only in set 1." + Environment.NewLine);
            }
            else
            {
                List<string> differences = new List<string>();
                if (!Object.Equals(fromView.GetAttributeValue<string>(AgViewsUtils.FieldDescription), toView.GetAttributeValue<string>(AgViewsUtils.FieldDescription)))
                {
                    differences.Add("Description");
                }
                if (!Object.Equals(fromView.GetAttributeValue<string>(AgViewsUtils.FieldFetchXml), toView.GetAttributeValue<string>(AgViewsUtils.FieldFetchXml)))
                {
                    differences.Add("Fetch XML");
                }
                if (!Object.Equals(fromView.GetAttributeValue<string>(AgViewsUtils.FieldLayoutXml), toView.GetAttributeValue<string>(AgViewsUtils.FieldLayoutXml)))
                {
                    differences.Add("Layout XML");
                }
                if (!Object.Equals(fromView.GetAttributeValue<int>(AgViewsUtils.FieldQueryType), toView.GetAttributeValue<int>(AgViewsUtils.FieldQueryType)))
                {
                    differences.Add("Query Type");
                }
                if (!Object.Equals(fromView.GetAttributeValue<string>(AgViewsUtils.FieldReturnedTypeCode), toView.GetAttributeValue<string>(AgViewsUtils.FieldReturnedTypeCode)))
                {
                    differences.Add("Returned Type Code");
                }

                if (differences.Count > 0)
                {
                    bool first = true;
                    sb.Append("   -- View \"");
                    sb.Append(fromView.GetAttributeValue<string>(AgViewsUtils.FieldName));
                    sb.Append("\" different: ");
                    foreach (string str in differences)
                    {
                        if (first)
                        {
                            first = false;
                        }
                        else
                        {
                            sb.Append(", ");
                        }

                        sb.Append(str);
                    }
                    sb.Append(".");
                    sb.Append(Environment.NewLine);
                }
            }

            if (sb.Length > 0)
            {
                diff.Append(sb.ToString());
            }
        }

        #endregion

    }
    */
}
